<template>
  <div class="demo">
    <h1>ProgressDemo</h1>
    <div>
      <button @click="addListItem">Add Task</button>
      <button @click="startAllTask">Start All</button>
      <button @click="pauseAllTask">Pause All</button>
      <button @click="clearDone">Clear Done</button>
    </div>

    <div class="list">
      <div
          v-for="item in list"
          :key="item.guid"
          class="list-item"
          :class="{pause: item.pause}"
      >
        <div class="name fg">
          <button @click="logItem(item)">{{ item.name }}</button>
        </div>
        <div class="progress-text">
          {{ item.progress }}%
        </div>
        <div class="progress" :style="{width: `${item.progress}%`}"></div>
        <div
            class="action fg">
          <button v-if="item.progress < 100" @click="togglePause(item)">{{ item.pause ? 'Resume' : 'Pause' }}</button>
          <span v-else style="margin-right: 10px;">Done</span>
          <button @click="removeItem(item)">Remove</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {ListItem} from '@/enum'
import {asyncPool, getRandomInt} from '@/utils/util'
import {TaskQueue} from '@/utils/task-queue'

export default {
  name: "ProgressDemo",
  data() {
    return {
      list: []
    }
  },
  mounted() {
    let i = 0
    while (i < 10) {
      i++
      this.addListItem()
    }

    // 初始化任务队列
    window.queue = this.queue = new TaskQueue({
      taskHandler: this.taskHandler
    })
    console.log(window.queue)
    this.queue.$on('allDone', () => {
      console.log('all done')
    })
    this.queue.$on('done', (task) => {
      console.log('done', task)
    })
  },
  beforeDestroy() {
    this.queue.$off('allDone')
    this.queue.$off('done')
  },
  methods: {
    // 添加列表项
    addListItem() {
      this.list.push(new ListItem({
        name: Math.random().toString(36).substr(2)
      }))
    },
    // 任务处理
    taskHandler(task) {
      console.log('taskHandler', task)
      const {data} = task
      return new Promise(resolve => {
        const addPercent = () => {
          // 任务执行结束
          if (data.progress >= 100) {
            data.pause = false
            return resolve(task)
          }

          // 随机加进度
          const p = getRandomInt(1, 5)
          const pp = getRandomInt(10, 20)
          setTimeout(() => {
            if (data.pause) {
              return resolve(task)
            }
            data.progress += pp
            addPercent()
          }, p * 100)
        }
        addPercent()
      })
    },
    // 启动任务
    startTask(item) {
      if (item.progress < 100) {
        item.pause = false
        this.queue.addTask(item)
      }
    },
    // 启动全部任务
    startAllTask() {
      this.list.forEach(item => {
        this.startTask(item)
      })
    },
    // 暂停全部任务
    pauseAllTask() {
      this.list.forEach(item => {
        if (item.progress < 100) {
          item.pause = true
        }
      })
    },
    // 清除已完成
    clearDone() {
      this.list = this.list.filter(item => item.progress < 100)
    },
    // 切换任务暂停
    togglePause(item) {
      item.pause = !item.pause
      if (!item.pause) {
        this.startTask(item)
      }
    },
    // 删除列表项（同时删除任务）
    removeItem(item) {
      item.pause = true // 任务Promise将停止
      if (item._tqTask) {
        this.queue.removeTask(item._tqTask)
      }
      const index = this.list.findIndex(v => v.guid === item.guid)
      if (index > -1) {
        this.list.splice(index, 1)
      }
    },
    logItem(item) {
      console.log(item)
    }
  }
}
</script>

<style lang="scss" scoped>
$border: grey; // #BCBCBC;
.list {
  margin-top: 10px;
  border: 1px solid $border;

  .list-item {
    height: 40px;
    padding: 0 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: relative;
    overflow: hidden;
    background: white; // #E6E6E6;

    & + .list-item {
      border-top: 1px solid $border;
    }

    .name {
      width: 10%;
    }

    .progress-text {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      z-index: 2;
    }

    .progress {
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      background: #a1d9a1; // #06B025;
      z-index: 1;
      transition: all .3s;
    }

    .fg {
      position: relative;
      z-index: 2;
    }

    &.pause {
      .progress {
        background: wheat; // #DACB26;
      }
    }
  }
}
</style>
